<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/

namespace Srv\Libs\Frame;

use Srv\Libs\Tools\ReflectionClassData;

abstract class EnumAbstract
{
    protected static array $valueToName = [0 => ''];    // default

    /**
     * @param int $value
     * @return string
     * getName
     */
    public static function getName(int $value):string
    {
        return static::$valueToName[$value]??'';
    }

    /**
     * @param string $name
     * @return int
     * getValue
     */
    public static function getValue(string $name):int
    {
        if(strlen($name) < 1) return 0;
        foreach (static::$valueToName as $valueItem => $nameItem){
            if($name === $nameItem) return $valueItem;
        }
        return 0;
    }

    /**
     * @return array
     * getNameList
     */
    public static function getNameList():array
    {
        return array_values(static::$valueToName);
    }

    /**
     * @return array
     * getValueList
     */
    public static function getValueList():array
    {
        return array_keys(static::$valueToName);
    }

    /**
     * @return array
     * getValueToNameList
     */
    public static function getValueToNameList():array
    {
        return static::$valueToName;
    }

    /**
     * @return array
     * getNameToValueList
     */
    public static function getNameToValueList():array
    {
        $nameToValue    = [];
        foreach (static::$valueToName as $valueItem => $nameItem){
            $nameToValue[$nameItem] = $valueItem;
        }
        return $nameToValue;
    }

    /**
     * @param string $name
     * @return string
     * parseName
     */
    public static function parseName(string $name):string
    {
        return self::nameExists($name) ? $name : '';
    }

    /**
     * @param $value
     * @return int
     * parseValue
     */
    public static function parseValue($value):int
    {
        if(!is_int($value)) $value = intval($value);
        return self::valueExists($value) ? $value : 0;
    }

    /**
     * @param string $name
     * @return bool
     * nameExists
     */
    public static function nameExists(string $name):bool
    {
        return in_array($name, static::$valueToName, true);
    }

    /**
     * @param int $value
     * @param bool $noZero
     * @return bool
     * valueExists
     */
    public static function valueExists(int $value, bool $noZero = false):bool
    {
        if($noZero && $value === 0) return false;
        return isset(static::$valueToName[$value]);
    }

    /**
     * @param int $value
     * @return string
     * getCommentByValue
     */
    public static function getCommentByValue(int $value):string
    {
        return self::getValueToCommentList()[$value]??'';
    }

    /**
     * @param string $name
     * @return string
     * getCommentByName
     */
    public static function getCommentByName(string $name):string
    {
        return self::getNameToCommentList()[$name]??'';
    }

    /**
     * @return array
     * getValueToCommentList
     */
    public static function getValueToCommentList():array
    {
        return self::getCommentList(true);
    }

    /**
     * @return array
     * getNameToCommentList
     */
    public static function getNameToCommentList():array
    {
        return self::getCommentList(false);
    }

    /**
     * @param bool $isValue
     * @return array
     * getCommentList
     */
    private static function getCommentList(bool $isValue):array
    {
        $commentList            = [];
        $refClassData           = ReflectionClassData::getRefDataByProto(static::class);
        if(!isset($refClassData['constantList']) || count($refClassData['constantList']) < 1) return $commentList;
        foreach($refClassData['constantList'] as $propertyName => $propertyItem){
            $propertyValue      = $propertyItem['value']??'';
            if(!is_numeric($propertyValue) || substr($propertyName, 0, 1) === '_') continue;
            $propertyValue      = intval($propertyValue);
            if($propertyValue < 1) continue;
            $propertyComment    = @preg_replace(['/(@?)\[/', '"]"'], [' `$1[', ']`'], $propertyItem['comment']??'');
            if(!is_string($propertyComment)) $propertyComment = '';
            if($isValue){
                $commentList[$propertyValue]    = $propertyComment;
            }else{
                $commentList[$propertyName]     = $propertyComment;
            }
        }
        return $commentList;
    }
}